package com.xy.blog.user.service.impl;

import com.xy.blog.core.event.PlatformEvent;
import com.xy.blog.core.exception.BaseException;
import com.xy.blog.core.id.SnowflakeIdWorker;
import com.xy.blog.core.springmvc.result.page.PageReq;
import com.xy.blog.core.springmvc.result.page.PageResp;
import com.xy.blog.user.controller.model.req.query.UserQuery;
import com.xy.blog.user.dao.impl.*;
import com.xy.blog.user.dao.model.OrganizationDO;
import com.xy.blog.user.dao.model.UserDO;
import com.xy.blog.user.dao.model.UserTemplateDO;
import com.xy.blog.user.dao.model.rel.UserAttrDO;
import com.xy.blog.user.dao.model.rel.UserOrgDO;
import com.xy.blog.user.mapstruct.UserAttrConverter;
import com.xy.blog.user.mapstruct.UserConverter;
import com.xy.blog.user.service.IUserService;
import com.xy.blog.user.service.event.UserDefaultOpenAccountEvent;
import com.xy.blog.user.service.model.UserAttrBO;
import com.xy.blog.user.service.model.UserBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zanhonglei
 * @version V1.0
 * @Description: 用户管理
 * @date 2019/10/30 22:54
 */
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserDaoImpl userDaoImpl;

    @Autowired
    private UserConverter userConverter;

    @Autowired
    private UserAttrRelDaoImpl userAttrRelDaoImpl;

    @Autowired
    private UserOrgDaoImpl userOrgDaoImpl;

    @Autowired
    private UserAttrConverter userAttrConverter;

    @Autowired
    private PlatformEvent platformEvent;

    @Autowired
    private UserTemplateDaoImpl userTemplateDaoImpl;

    @Autowired
    private OrganizationDaoImpl organizationDaoImpl;

    @Override
    public PageResp<UserBO> listPage(PageReq<UserQuery> req) {
        PageResp<UserBO> pageResp = userConverter.do2Bo(userDaoImpl.listByPage(req));
        pageResp.getList().forEach(item->{
            Long userId = item.getId();
            UserOrgDO userOrgDO = userOrgDaoImpl.getByUserId(userId);
            Long orgId = userOrgDO.getOrgId();
            item.setOrgId(orgId);
            OrganizationDO organizationDO = organizationDaoImpl.getById(orgId);
            item.setOrgName(organizationDO.getName());
            item.setAttrDict(userAttrConverter.do2Bo(userAttrRelDaoImpl.getByUserId(userId)));
            UserTemplateDO userTemplateDO = userTemplateDaoImpl.getById(item.getUserTemplateId());
            item.setUserTemplateName(userTemplateDO.getName());
        });
        return pageResp;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void saveUser(UserBO userBO) throws BaseException {

        Long userId = SnowflakeIdWorker.generateId();
        LocalDateTime now = LocalDateTime.now();
        UserDO userDO = new UserDO();
        userDO.setId(userId);
        userDO.setUserCode(userBO.getUserCode());
        userDO.setUserName(userBO.getUserName());
        userDO.setCreateTime(now);
        userDO.setUpdateTime(now);
        Long userTemplateId = userBO.getUserTemplateId();
        userDO.setUserTemplateId(userTemplateId);
        userDaoImpl.save(userDO);

        UserOrgDO userOrgDO = new UserOrgDO();
        userOrgDO.setCreateTime(now);
        userOrgDO.setUpdateTime(now);
        userOrgDO.setId(SnowflakeIdWorker.generateId());
        userOrgDO.setUserId(userId);
        userOrgDO.setOrgId(userBO.getOrgId());
        userOrgDaoImpl.save(userOrgDO);

        Map<Long, String> attrDict = userBO.getAttrDictMaps();
        attrDict.forEach((key,value)->{
            UserAttrDO userAttrDO = new UserAttrDO();
            userAttrDO.setAttrDictId(key);
            userAttrDO.setUserId(userId);
            userAttrDO.setValue(value);
            userAttrDO.setId(SnowflakeIdWorker.generateId());
            userAttrDO.setCreateTime(now);
            userAttrDO.setUpdateTime(now);
            userAttrRelDaoImpl.save(userAttrDO);
        });

        // 默认开通账号
        UserTemplateDO userTemplateDO = userTemplateDaoImpl.getById(userTemplateId);
        platformEvent.publish(new UserDefaultOpenAccountEvent(this,userId,userTemplateDO.getDefaultOpenAccountAttrId()));

    }

    @Override
    @Async
    @Transactional(rollbackFor = Throwable.class)
    public void deleteById(Long id) {
        userDaoImpl.deleteById(id);
        userOrgDaoImpl.deleteByUserId(id);
        userAttrRelDaoImpl.deleteByUserId(id);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateUser(UserBO userBO) {
        //TODO
    }

    @Override
    public UserBO getUserById(Long id) {
        UserDO userDO = userDaoImpl.getById(id);
        UserBO userBO = userConverter.do2Bo(userDO);
        Long userId = userDO.getId();
        List<UserAttrDO> byUserId = userAttrRelDaoImpl.getByUserId(id);
        List<UserAttrBO> userAttrBOS = userAttrConverter.do2Bo(byUserId);
        userBO.setAttrDict(userAttrBOS);
        UserOrgDO userOrg = userOrgDaoImpl.getByUserId(userId);
        userBO.setOrgId(userOrg.getOrgId());
        Map<Long, String> maps = new HashMap<>();
        userAttrBOS.forEach(item->{
            maps.put(item.getAttrDictId(), item.getValue());
        });
        userBO.setAttrDictMaps(maps);
        return userBO;
    }
}
